﻿using UnityEngine;
using XLua;
using System;
using System.Globalization;

namespace Kylin
{

    public class NetworkManager : IManager
    {
        public static NetworkManager Instance = new NetworkManager();


        private Connection client;
        private DisruptorUnity3d.RingBuffer<byte[]> queue = new DisruptorUnity3d.RingBuffer<byte[]>(64);


        public void OnInitialize()
        {
            client = new Connection();
        }

        public void OnUpdateLogic()
        {
            //http
            HttpHelper.HttpInvoke();

            byte[] data;
            for (;;)
            {
				bool success = queue.TryDequeue(out data);
                if (!success)
                {
                    return;
                }
                try
                {
					int msgId = ((int) (data[0]) << 8) | ((int) (data[1]) & 0x0000ff);
					byte[] pbData = new byte[data.Length - 2];
					Buffer.BlockCopy(data, 2, pbData, 0, data.Length - 2);
					CSharpCallLuaDelegates.Instance.LuaNetworkEntry.onReceiveMsg(msgId, pbData);
                }
                catch (Exception ex)
                {
#if UNITY_EDITOR
                    //UnityEngine.Debug.LogErrorFormat("处理消息出错 {0}", ex.ToString());
#endif
                }
            }
        }

        public void queueMsg(byte[] func)
        {
            queue.Enqueue(func);
        }

        public void OnDestruct()
        {
            OnDisconnect();
            client = null;
            Debug.Log("~NetworkManager was destroyed!");
        }   

        [LuaCallCSharp]
        public void Connect(string remoteAddress, int remotePort)
        {
            if(client != null)
            {
                client.Connect(remoteAddress, remotePort);
            }
                
        }

        [LuaCallCSharp]
        public void SendMessage(int msgId, byte[] data)
        {
            if (client != null) {
				int size = data.Length + 4;
				byte[] stream = new byte[size];
				stream [0] = (byte) ((size >> 8) & 0x000000ff);
				stream [1] = (byte) (size & 0x000000ff);
				stream [2] = (byte) ((msgId >> 8) & 0x000000ff);
				stream [3] = (byte) (msgId & 0x000000ff);
				Buffer.BlockCopy (data, 0, stream, 3, data.Length);
				client.SendMessage(stream);
            }
        }

        [LuaCallCSharp]
        public void OnDisconnect()
        {
            if (client != null)
            {
                client.Close();
            }
        }

        private byte[] ConvertHexStringToByteArray(string hexString)
        {
            if (hexString.Length % 2 != 0)
            {
                throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
            }

            byte[] HexAsBytes = new byte[hexString.Length / 2];
            for (int index = 0; index < HexAsBytes.Length; index++)
            {
                string byteValue = hexString.Substring(index * 2, 2);
                HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
            }

            return HexAsBytes;
        }
    }
}